package com.bkgy.modularbx.slip.service.imp;

import com.bkgy.modularbx.slip.entity.RollData;
import com.bkgy.modularbx.slip.entity.RollMappingConfiguration;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 轧辊数据缓冲服务类，用于管理和维护轧辊运行数据的实时缓存。
 * 该服务使用线程安全的数据结构（ConcurrentHashMap和Deque）来存储每个轧辊的最新数据点序列，
 * 主要用于支持轧辊打滑检测和分析功能，确保数据的实时性和可靠性。
 *
 * @author Trae
 * @version 1.0
 * @see RollData
 * @see RollMappingConfiguration
 */
@NoArgsConstructor(force = true)
@Service
public class DataBufferService {
    /** 轧辊数据缓冲区，key为轧辊ID，value为该轧辊的数据点队列 */
    private final Map<String, Deque<RollData>> dataBuffer = new ConcurrentHashMap<>();
    
    /** 轧辊映射配置，包含缓冲区大小等监控参数 */
    private final RollMappingConfiguration config;

    @Autowired
    public DataBufferService(RollMappingConfiguration config) {
        this.config = config;
    }

    /**
     * 添加一个新的数据点到指定轧辊的缓冲区。
     * 如果该轧辊的缓冲区不存在，会自动创建一个新的缓冲区。
     * 当缓冲区大小超过配置的限制时，会自动移除最旧的数据点。
     *
     * @param rollId 轧辊唯一标识符
     * @param data 待添加的轧辊数据点
     */
    public void addDataPoint(String rollId, RollData data) {
        if (!dataBuffer.containsKey(rollId)) {
            dataBuffer.put(rollId, new LinkedList<>());
        }

        Deque<RollData> rollBuffer = dataBuffer.get(rollId);
        rollBuffer.addLast(data);

        // 保持缓冲区大小固定
        int bufferSize = config.getMonitoringConfig().getDataBufferSize();
        while (rollBuffer.size() > bufferSize) {
            rollBuffer.removeFirst();
        }
    }

    /**
     * 获取指定轧辊的最近数据点列表。
     * 如果该轧辊的缓冲区不存在，返回空列表。
     *
     * @param rollId 轧辊唯一标识符
     * @return 包含该轧辊最近数据点的列表
     */
    public List<RollData> getRecentData(String rollId) {
        return new ArrayList<>(dataBuffer.getOrDefault(rollId, new LinkedList<>()));
    }

    /**
     * 获取所有轧辊的缓存数据。
     * 将所有轧辊的数据队列转换为列表形式返回。
     *
     * @return 包含所有轧辊数据的映射，key为轧辊ID，value为数据点列表
     */
    public Map<String, List<RollData>> getAllBufferedData() {
        Map<String, List<RollData>> result = new HashMap<>();
        for (Map.Entry<String, Deque<RollData>> entry : dataBuffer.entrySet()) {
            result.put(entry.getKey(), new ArrayList<>(entry.getValue()));
        }
        return result;
    }

    /**
     * 清除指定轧辊的数据缓冲区。
     *
     * @param rollId 轧辊唯一标识符
     */
    public void clearBuffer(String rollId) {
        dataBuffer.remove(rollId);
    }

    /**
     * 清除所有轧辊的数据缓冲区。
     * 通常在系统重启或需要重置所有数据时使用。
     */
    public void clearAllBuffers() {
        dataBuffer.clear();
    }
}
